﻿using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Input;
using Gencode.VECore.VectorShape;

namespace Gencode.VECore
{
    public delegate void ShapeChangedEventHandler(object sender, ShapeChangedEventArgs e);

	public class CanvasLayer : Canvas, IDisposable
	{
        public event ShapeChangedEventHandler ShapeChanged;
        public event ShapeChangedEventHandler ShapeMoved;
        public event ShapeChangedEventHandler ShapeAdded;
        public event ShapeChangedEventHandler ShapeDeleted;

        bool selecteable = true;
        public bool Selecteable
        {
            get
            {
                return selecteable;
            }
            set
            {
                selecteable = value;
                if (ShapeList != null)
                    foreach (VECShape shape in ShapeList)
                        shape.Selecteable = selecteable;
            }
        }

		Gencode.VECore.Tools.VectorTool _curentTool;
        public Gencode.VECore.Tools.VectorTool CurentTool
        {
            set
            {
                _curentTool = value;
            }
        }
        
        ShapeList _shapeList;
        /// <summary>
        /// List of shapes that are on the canvas
        /// </summary>
        public ShapeList ShapeList
        {
            get
            {
                return _shapeList;
            }
            set
            {
                _shapeList = value;
            }
        }

		public CanvasLayer()
			: base()
		{
            _shapeList = new ShapeList();
		}

        public void Dispose()
        {
            while (ShapeList.Count > 0)
            {
                this.Children.Remove(ShapeList[0]);
                this.ShapeList.RemoveAt(0);
            }
        }

        private void OnShapeChanged(object sender, EventArgs e)
        {
            if (ShapeChanged != null)
                ShapeChanged(this, new ShapeChangedEventArgs(sender as VECShape));
        }

        private void OnShapeMoved(object sender, EventArgs e)
        {
            if (ShapeMoved != null)
                ShapeMoved(this, new ShapeChangedEventArgs(sender as VECShape));
        }

        /// <summary>
        /// Replace shape specified shape.
        /// Retruns false if failed to repalce
        /// </summary>
        /// <param name="originalShape"></param>
        /// <param name="newShape"></param>
        /// <returns></returns>
        public bool Replace(VECShape originalShape, VECShape newShape)
        {
            bool retval = ShapeList.Replace(originalShape, newShape);
            Refresh();

            return retval;
        }

        public void AddShape(VECShape shape)
        {
            ShapeList.UnselectAll();
            ShapeList.Add(shape);
            Children.Add(shape);

            shape.ShapeMoved += new ChangedEventHandler(OnShapeMoved);
            shape.ShapeSizeChanged += new ChangedEventHandler(OnShapeChanged);

            if (ShapeAdded != null)
                ShapeAdded(this, new ShapeChangedEventArgs(shape));
        }

        public void RemoveShape(VECShape shape)
        {
            ShapeList.Remove(shape);

            if (ShapeDeleted != null)
                ShapeDeleted(this, new ShapeChangedEventArgs(shape));
        }

        public void RemoveSelection()
        {
            foreach (VECShape shape in ShapeList)
            {
                if (shape.Selected)
                {
                    Children.Remove(shape);
                    ShapeList.Remove(shape);

                    if (ShapeDeleted != null)
                        ShapeDeleted(this, new ShapeChangedEventArgs(shape));
                }
            }
        }

        public void Refresh()
        {
            this.Children.Clear();
            foreach (VECShape shape in ShapeList)
            {
                this.Children.Add(shape);
            }
        }
    }

    public class ShapeChangedEventArgs : EventArgs
    {
        VECShape changedshape;

        public ShapeChangedEventArgs(VECShape changedshape)
        {
            this.changedshape = changedshape;
        }

        public VECShape ChangedShape
        {
            get
            {
                return changedshape;
            }
        }
    }
}
